<?php
namespace Pinenut\Service\UrlManager;

use Pinenut\Service\UrlManager;

/**
 *
 * @author kosh
 *        
 *         Добавляем детект языка и запихиваем его в глобальный параметр
 *         Так же генерить адресацию в зависимости от языка
 *        
 *         Формат включения языка в адрес:
 *        
 *         было: /some-url?asda=ggg
 *         стало /ru/some-url?asda=ggg
 *        
 */
class WithLanguage extends UrlManager {

	public function parseUrl($url = null, $method = null, $host = null, $params = null) {
		
		// достаём конфу, проверяем на наличие префикса
		$languages = \MultilangConfig::get();
		
		$langId = null;
		
		// ищем язык в адресе, если находим - то вырезаем его
		$prefixesPattern = implode('|', array_keys($languages));
		
		if (preg_match('#^\/(' . $prefixesPattern . ')\/#', $url, $match)) {
			$url = preg_replace('#^\/(' . $prefixesPattern . ')#', '', $url);
			$langId = $match[1];
		}
		
		if (! $langId) {
			// если язык не указан явно
			// берём его из запроса
			$langId = static::getAcceptLanguage($languages);

		}
		
		if (! $langId) {
			// если язык всё еще не определили - берём дефолтный
			foreach ($languages as $id => $config) {
				if ($config['default']) {
					$langId = $id;
					break;
				}
			}
		}
		
		$request = parent::parseUrl($url, $method, $host, $params);
		
		// устанавливаем глобал если нашли
		if ($request && $langId) {
			$params = $request->globalParams();
			$params['_langId'] = $langId;
			$request->globalParams($params);
		}
		
		return $request;
	}

	public function createUrl($action, array $params, $abs = false, $scheme = null) {
		
		// идентификатор языка может быть задан явно, тогда глобальные данные не используем
		$langId = null;
		
		if (isset($params['_langId'])) {
			$langId = $params['_langId'];
			unset($params['_langId']);
		} else {
			// получаем глобальные параметры и игнорируем некоторые,
			// если указано в действии
			$context = \Dispatcher::$currentContext;
			
			// надо ли добавить глобальные параметры в урл? мне кажется нет
			$globalParams = $context->globalParams;
			
			$langId = isset($globalParams['_langId']) ? $globalParams['_langId'] : null;
		}
		
		$url = parent::createUrl($action, $params, $abs, $scheme);
		
		// \Request::actionNameToClassName($action));
		// $params = array_merge($params, $globalParams);
		
		$className = \Request::actionNameToClassName($action);
		$ignore = $className::ignoreParams();
		
		if (! in_array('_langId', (array) $ignore) && $langId) {
			
			$parsed_url = parse_url($url);
			$parsed_url['path'] = '/' . $langId . $parsed_url['path'];
			$url = static::unparse_url($parsed_url);
		}
		
		return $url;
	}

	/**
	 * Определяет какой язык из поддерживаемых браузером подходит нам больше всего (по конфе)
	 * @param unknown $config
	 * @return unknown
	 */
	static function getAcceptLanguage($config) {
		$langId = null;
		$languages = [];
		if (preg_match_all('/([a-z]{1,8}(?:-[a-z]{1,8})?)(?:;q=([0-9.]+))?/', 
			strtolower($_SERVER['HTTP_ACCEPT_LANGUAGE']), $matches, 
			PREG_SET_ORDER)) {
			
			foreach ($matches as $match) {
				$languages[$match[1]] = isset($match[2]) ? $match[2] : 1;
			}
		}
		
		// выбираем подходящий
		foreach ($languages as $accept => $q) {
			foreach ($config as $id => $conf) {
				if (in_array($accept, (array) $conf['accept'])) {
					$langId = $id;
					break;
				}
			}
			if ($langId) {
				break;
			}
		}
		
		return $langId;
	}
}